/*
 *  Created on: Jun 5, 2009
 *      Author: Ramesh Rajaby
 */

#include "../Shared.h"
#include "../Bytecode/BytecodeStructures.h"


namespace SymphonyBC {


class BCFileWriter {
public:
	static void writeClass(ClassBC* classBC) {
		string filename = classBC->getName() + CompilerOptions::COMPILED_EXTENSION;
		ofstream fout(filename.c_str(), ios::binary);

		writeStringOnFile(fout, classBC->getDataArea());
#ifdef DEBUG
cout << "=== dataArea size: " << classBC->getDataArea().length() << " ===" << endl << endl;
#endif

		vector<MethodBC*> classMethods = classBC->getMethods();

		int nMethods = classMethods.size();
		fout.write((char*)&nMethods, sizeof(nMethods));
		for (int i = 0; i < (int)classMethods.size(); i++) {
			MethodBC* methodBC = classMethods[i];
			writeMethod(methodBC, fout);
		}
	}

	static void writeMethod(MethodBC* methodBC, ofstream& fout) {
		//int returnType = methodBC->getReturnType();
		//fout.write((char*)&returnType, sizeof(returnType));

		writeStringOnFile(fout, methodBC->getName());

		int size = methodBC->getInstructions().size();
#ifdef DEBUG
cout << methodBC->getName() << endl;
cout << size << endl;
#endif
		fout.write((char*)&size, sizeof(size));
		BOOST_FOREACH(InstructionBC* instruction, methodBC->getInstructions()) {
			fout.write((char*)&(instruction->opcode), sizeof(instruction->opcode));
			fout.write((char*)&(instruction->op1), sizeof(instruction->op1));
			fout.write((char*)&(instruction->op2), sizeof(instruction->op2));
			fout.write((char*)&(instruction->op3), sizeof(instruction->op3));
#ifdef DEBUG
cout << instruction->opcode << " " << instruction->op1 << " " << instruction->op2 << " " << instruction->op3 << endl;
#endif
		}

#ifdef DEBUG
cout << endl;
#endif
	}
};


}
